﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.IO.Compression;

namespace Velocity.Ink
{
    public static class GZipHelper
    {

        public static long Compress(Stream input, Stream output)
        {

            // Create a buffer to transfer the data  
            byte[] buffer = new byte[1024];
            int bytesRead = 0;
            long totalBytes = 0;

            // Get the stream that will perform the decompression  
            using (Stream zip = new GZipStream(output, CompressionMode.Compress))
            {

                // Use the buffer to move data to the compression stream until complete  
                while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
                {

                    totalBytes += bytesRead;
                    zip.Write(buffer, 0, bytesRead);

                }

                // Close the compression stream  
                zip.Close();

            }

            // Return the total number of bytes of compressed data  
            return totalBytes;

        }

        public static long Decompress(Stream input, Stream output)
        {

            // Create a buffer to transfer the data  
            byte[] buffer = new byte[1024];
            int bytesRead = 0;
            long totalBytes = 0;

            // Get the stream that will perform the decompression  
            using (Stream zip = new GZipStream(input, CompressionMode.Decompress, true))
            {

                // Use the buffer to move data to the compression stream until complete  
                while ((bytesRead = zip.Read(buffer, 0, buffer.Length)) > 0)
                {

                    totalBytes += bytesRead;
                    output.Write(buffer, 0, bytesRead);

                }

                // Close the compression stream  
                zip.Close();

            }


            // Returns the total number of bytes of decompressed data  
            return totalBytes;

        }

        public static byte[] Compress(byte[] data)
        {

            byte[] final;

            // Create a stream to hold the output  
            using (MemoryStream output = new MemoryStream(), input = new MemoryStream(data))
            {

                // Process the compression  
                Compress(input, output);

                // Get the resultant data  
                final = output.ToArray();

                // Close the underlying streams  
                input.Close();
                output.Close();

            }

            // Convert the output stream to a byte array  
            return final;

        }

        public static byte[] Decompress(byte[] gzipData)
        {

            byte[] final;

            // Create a stream to hold the output  
            using (MemoryStream output = new MemoryStream(), input = new MemoryStream(gzipData))
            {

                // Process the compression  
                Decompress(input, output);

                // Get the resultant data  
                final = output.ToArray();

                // Close the underlying streams  
                input.Close();
                output.Close();

            }

            // Convert the output stream to a byte array  
            return final;

        }

        public static string Compress(string data)
        {

            // get a byte array of the data and pass to the Compress method.  
            return Convert.ToBase64String(Compress(Encoding.Default.GetBytes(data)));

        }

        public static string Decompress(string gzipString)
        {

            // Decompress and convert data to a string  
            byte[] b = Decompress(Convert.FromBase64String(gzipString));
            return Encoding.Default.GetString(b, 0, b.Length);

        }

        public static string Decompress(Stream input)
        {

            byte[] final;

            // Create a stream to hold the output  
            using (MemoryStream output = new MemoryStream())
            {

                // Process the compression  
                Decompress(input, output);

                // Get the resultant data  
                final = output.ToArray();

                // Close the underlying streams  
                input.Close();
                output.Close();

            }

            // we get the string  
            return Encoding.Default.GetString(final, 0, final.Length);

        }

    } 
}
